import socket
import threading
from io import BytesIO

import pymysql
import csv
import time

headers = ['service_id','pm25','pm10','noise','tem','hum','wind_dir','wind_speed','press','TSP','update_time']

def creat_csv(headers):
    with open('../iotData.csv','w',newline='') as f:
        writer = csv.DictWriter(f,headers)
        writer.writeheader()

def append_csv(data):  #  每次都是一个dict
    with open('../iotData.csv','a+',newline='') as f:
        writer = csv.DictWriter(f,headers)
        writer.writerow(data)

def db_oper(data):

    # service_id,pm25,pm10,noise,tem,hum,wind_dir,wind_speed,press,TSP,update_time
    lis = []
    lis.append(data['service_id'])
    lis.append(data['pm25'])
    lis.append(data['pm10'])
    lis.append(data['noise'])
    lis.append(data['tem'])
    lis.append(data['hum'])
    lis.append(data['wind_dir'])
    lis.append(data['wind_speed'])
    lis.append(data['press'])
    lis.append(data['TSP'])
    lis.append(data['update_time'])
    # db = pymysql.connect(host='localhost', user='root', password='root', database='iotdata')
    db = pymysql.connect(host='localhost', user='root',password='server2008Admin',database='iotdata')
    cursor = db.cursor()
    sql = 'insert into iot(service_id,pm25,pm10,noise,tem,hum,wind_dir,wind_speed,press,TSP,update_time) values (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)'
    cursor.execute(sql,lis)
    db.commit()
    db.close()

def judge(data):  # 风向的判断
    try:
        if data == 0:
            return  '东北偏北'
        elif data == 1:
            return '东北'
        elif data == 2:
            return '东北偏东'
        elif data == 3:
            return '正东'
        elif data == 4:
            return '东南偏东'
        elif data == 5:
            return  '东南'
        elif data == 6:
            return  '东南偏南'
        elif data == 7:
            return  '正南'
        elif data == 8:
            return  '西南偏南'
        elif data == 9:
            return  '西南'
        elif data == 10:
            return  '西南偏西'
        elif data == 11:
            return  '正西'
        elif data == 12:
            return  '西北偏西'
        elif data == 13:
            return  '西北'
        elif data == 14:
            return  '西北偏北'
        elif data == 15:
            return  '正北'
    except BaseException:
        print('---------------风向解析错误------------------------')

def data_save(data):   # data是一个dict

    dic = {}

    f = BytesIO(data)
    f.read(2)   # 帧头
    f.read(1)   # 版本

    service_id = f.read(6)
    dic['service_id'] = int.from_bytes(service_id, byteorder='big', signed=False)  # 设备ID

    f.read(4)
    f.read(1)
    f.read(2)

    pm25 = f.read(4)
    dic['pm25'] = int.from_bytes(pm25, byteorder='big', signed=False)   # PM2.5
    pm10 = f.read(4)
    dic['pm10'] = int.from_bytes(pm10, byteorder='big', signed=False)   # pM10

    noise = f.read(4)
    dic['noise'] = int.from_bytes(noise, byteorder='big', signed=False)   # 噪声 0.1



    pre_data = int.from_bytes(f.read(4), byteorder='big', signed=False)
    if pre_data > 500:
        tem = 0-(pow(16,8)-pre_data)
    else:
        tem = pre_data
    dic['tem'] = tem   # 温度 求补码  0.1


    dic['hum'] = int.from_bytes(f.read(4), byteorder='big', signed=False)  # 湿度  0.1

    a = int.from_bytes(f.read(4), byteorder='big', signed=False)   # 风向 判断规则 循环
    dic['wind_dir'] = judge(a)

    dic['wind_speed'] = int.from_bytes(f.read(4), byteorder='big', signed=False)   # 风速    0.1
    dic['press'] = int.from_bytes(f.read(4), byteorder='big', signed=False)   # 大气压   0.001
    dic['TSP'] = int.from_bytes(f.read(4), byteorder='big', signed=False)   # TSP

    update_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
    dic['update_time'] = update_time

    print(dic)
    # creat_csv(headers)
    db_oper(dic)
    append_csv(dic)



    return dic

# 全局变量
i = 20  # 可以同时连接的数量
nowConnectNum = 0  # 目前连接的数量

def tcpLink(sock, addr, nowConnectNum):  #  接收一个连接 并 把端口给他
        sock.send(b'Connection successful')
        print(' %s:%s 客户端已连接' % addr )
        # print('当前已有%d个连接'% nowConnectNum)
        while True:
            data = sock.recv(1024)
            if not data:
                 break
            print(data,type(data))

            data_save(data)

            # 原始数据存日志
            print(data.hex())
            with open('../backup.log', 'a+') as f:
                f.write(data.hex() + "****" + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) + "\n")
            print('来自 %s:%s 的数据接收成功' % addr)
            sock.send('Data sent successfully'.encode('utf8'))
        # print('Connection from %s:%s has closed ' % addr)

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

s.bind(('',9319))  # 绑定一个监听端口
s.listen(i)  # 最多连接五个
print('等待连接')

while True:
    sock,addr = s.accept()  # 接受一个新的连接
    # nowConnectNum += 1;

    t = threading.Thread(target=tcpLink,args=(sock,addr,nowConnectNum))
    t.start()


